package com.tcgroup.phone.base_core.framework.mvvm.activity;

import android.content.Intent;
import android.os.Bundle;

import androidx.annotation.IdRes;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider.Factory;
import androidx.lifecycle.ViewModelProviders;

import com.tcgroup.phone.base_core.framework.mvvm.AbstractActivity;
import com.tcgroup.phone.base_core.framework.mvvm.viewmodel.BaseViewModel;

import java.util.Map;

/**
 * 作者: wangfei
 * 创建时期: 2020/3/16.
 * 包名: com.tcgroup.phone.base_core.framework.mvvm
 * 类名: HibeautyNew-Android
 */
public abstract class ContainerMvvmActivity<V extends ViewDataBinding,VM extends BaseViewModel> extends AbstractActivity {

    protected V mBinding;
    protected VM mViewModel;
    private int viewModelId;


    @Override
    public void initContentView() {
        super.initContentView();
        initViewDataBinding();
        initBaseViewObservable();
    }

    private void initViewDataBinding() {
        mBinding = DataBindingUtil.setContentView(this,onBindLayout());
        viewModelId = onBindVariableId();
        mViewModel = createViewModel();
        if(mBinding != null){
            mBinding.setVariable(viewModelId, mViewModel);
        }
        getLifecycle().addObserver(mViewModel);
    }

    public VM createViewModel(){
        return ViewModelProviders.of(this,onBindViewModelFactory()).get(onBindViewModel());
    }

    public void initBaseViewObservable(){
        initViewObservable();
        mViewModel.getUC().getShowInitLoadViewEvent().observe(this, (Observer<Boolean>) o -> {
            if (o){
                showLoading();
            }
        });
        mViewModel.getUC().getShowCurrentEventEvent().observe(this, (Observer<Boolean>) o -> {
            if (o){
                showContent();
            }
        });
        mViewModel.getUC().getShowNoDataViewEvent().observe(this,(Observer<Boolean>)  o -> {
            if (o){
                showEmpty();
            }
        });
        mViewModel.getUC().getShowNetWorkErrViewEvent().observe(this,(Observer<Boolean>)  o -> {
            if (o){
                showError();
            }
        });
        mViewModel.getUC().getStartActivityEvent().observe(this, (Observer<Map<String, Object>>) params -> {
            Class<?> clz = (Class<?>) params.get(BaseViewModel.ParameterField.CLASS);
            Bundle bundle = (Bundle) params.get(BaseViewModel.ParameterField.BUNDLE);
            startActivity(clz, bundle);
        });
        mViewModel.getUC().getFinishActivityEvent().observe(this,(Observer<Boolean>)  o -> {
            if (o){
                finish();
            }
        });
        mViewModel.getUC().getOnBackPressedEvent().observe(this,(Observer<Boolean>)  o -> {
           onBackPressed();
        });
    }

    public void startActivity(Class<?> clz, Bundle bundle) {
        Intent intent = new Intent(this, clz);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivity(intent);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(mBinding != null){
            mBinding.unbind();
        }
    }

    @Override
    public void initView() {
        mViewModel.initViewByReFresh();
    }

    @Override
    public void initData() { }

    @Override
    public void initListener() { }


    public abstract int onBindVariableId();
    public abstract Class<VM> onBindViewModel();
    public abstract Factory onBindViewModelFactory();
    public abstract void initViewObservable();


    public void switchContent(Fragment from, Fragment to, @IdRes int layoutId , String tag) {
        if (from == null || to == null) {
            return;
        }
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        if (!to.isAdded()) {
            transaction.hide(from).add(layoutId, to, tag).commit();
        } else {
            transaction.hide(from).show(to).commit();
        }
    }

}
